package com.koron.order.risk.base.excel;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.util.ListUtils;
import com.koron.common.core.business.common.entity.TOrderNoMax;
import com.koron.common.core.business.common.service.TOrderNoMaxService;
import com.koron.order.linepatrol.satellite.excel.LineAnalysisEventListener;
import com.koron.order.overhaul.bean.dto.Equipment;
import com.koron.order.risk.base.bean.convertor.LineRiskConvertor;
import com.koron.order.risk.base.bean.po.LineRiskPart;
import com.koron.order.risk.base.bean.vo.LineRiskExcel;
import com.koron.order.risk.base.bean.vo.LineRiskVO;
import com.koron.order.risk.base.service.LineRiskService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.ADOConnection;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author jzp
 * @since 2023/1/10
 */
@Slf4j
@RequiredArgsConstructor
public class RiskExcelListener extends LineAnalysisEventListener<LineRiskExcel> {

    private final LineRiskService lineRiskService;
    private final LineRiskConvertor lineRiskConvertor;
    private final TOrderNoMaxService tOrderNoMaxService;

    // 每隔100条，然后清理list ，方便内存回收
    private static final int BATCH_COUNT = 100;
    // 要保存的数据
    private final List<LineRiskVO> LineRiskVOList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    @Override
    public void invoke(LineRiskExcel data, AnalysisContext context) {
        LineRiskVO lineRiskVO = fillData(data);
        if (lineRiskVO == null) {
            return;
        }
        LineRiskVOList.add(lineRiskVO);
        if (LineRiskVOList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            LineRiskVOList.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        log.info("所有数据解析完成！");
    }

    private void saveData() {
        // 设置编码
        TOrderNoMax maxNo = tOrderNoMaxService.peekNoMax(LineRiskService.codePrefix, null, LineRiskVOList.size());
        String prefix = LineRiskService.codePrefix + maxNo.getDate();
        AtomicInteger atomicInteger = new AtomicInteger(maxNo.getMaxValue() - LineRiskVOList.size());
        for (LineRiskVO lineRiskVO : LineRiskVOList) {
            lineRiskVO.setCode(prefix + String.format("%0" + 3 + "d", atomicInteger.getAndIncrement()));
        }

        log.info("{}条风险管控单数据，开始存储数据库！", LineRiskVOList.size());
        ADOConnection.runTask(getCurrDs(), lineRiskService, "saveBatch", Boolean.class, LineRiskVOList);
        log.info("存储数据库成功！");
    }

    /**
     * 填充数据字段
     */
    private LineRiskVO fillData(LineRiskExcel data) {
        if (data == null) {
            return null;
        }
        LineRiskVO lineRiskVO = lineRiskConvertor.excelToVo(data);

        // riskParentType默认高压线路
        lineRiskVO.setRiskParentType("高压线路");

        // 线路
        if (StrUtil.isEmpty(lineRiskVO.getEquipmentName())) {
            fillError(data, 1, "线路不能为空");
            return null;
        }
        Equipment line = getLineByName(lineRiskVO.getEquipmentName());
        if (line == null) {
            fillError(data, 1, "线路：" + lineRiskVO.getEquipmentName() + "不存在");
            return null;
        } else if (CollUtil.isEmpty(line.getChildren())) {
            fillError(data, 1, "该线路：" + lineRiskVO.getEquipmentName() + "下没有杆塔");
            return null;
        } else {
            lineRiskVO.setEquipmentId(line.getId());
        }

        // 塔段
        if (StrUtil.isEmpty(data.getLineRiskPartStr())) {
            fillError(data, 2, "杆塔不能为空");
            return null;
        }
        List<Equipment> tower = getTowersByNamesAndChildren(line.getName(), data.getLineRiskPartStr(), line.getChildren());
        if (tower == null) {
            fillError(data, 2, "杆塔：" + data.getLineRiskPartStr() + "不存在");
            return null;
        } else if (tower.isEmpty()) {
            fillError(data, 2, "只需要填写第一个和最后一个杆塔即可");
            return null;
        } else {
            List<LineRiskPart> partList = tower.stream().map(e -> {
                LineRiskPart lineRiskPart = new LineRiskPart();
                lineRiskPart.setEquipmentId(e.getId());
                lineRiskPart.setEquipmentName(e.getName());
                return lineRiskPart;
            }).collect(Collectors.toList());
            lineRiskVO.setLineRiskPartList(partList);
        }

        // 跟进部门
        if (StrUtil.isEmpty(lineRiskVO.getFollowDeptName())) {
            fillError(data, 3, "跟进部门不能为空");
            return null;
        }
        String followDeptId = getDeptIdByName(lineRiskVO.getFollowDeptName());
        if (followDeptId == null) {
            fillError(data, 3, "跟进部门：" + lineRiskVO.getFollowDeptName() + "不存在");
            return null;
        } else if ("".equals(followDeptId)) {
            fillError(data, 3, "跟进部门：" + lineRiskVO.getFollowDeptName() + "在数据库中重复，请在跟进部门名称后加上|部门id，如：测试水司|000001");
            return null;
        } else {
            lineRiskVO.setFollowDeptId(followDeptId);
        }

        // 发现人
        if (StrUtil.isEmpty(lineRiskVO.getFinderName())) {
            fillError(data, 3, "发现人不能为空");
            return null;
        }
        String finder = getStaffAccountByName(lineRiskVO.getFinderName());
        if (finder == null) {
            fillError(data, 10, "用户名：" + lineRiskVO.getFinderName() + "不存在");
            return null;
        } else if ("".equals(finder)) {
            fillError(data, 10, "用户名：" + lineRiskVO.getFinderName() + "在数据库中重复，请在用户名后加上|用户账号，如：张三|zhangsan");
            return null;
        } else {
            lineRiskVO.setFinder(finder);
        }
        return lineRiskVO;
    }

}
